package org.gwtEss.gwtExtensions;

import java.util.ArrayList;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.FlexTable;

public class FlexEventsTable extends FlexTable{

	TableMouseListenerCollection listeners;
	
	public FlexEventsTable() {
		super();
		sinkEvents(Event.MOUSEEVENTS | Event.ONCLICK); 
	}

	@Override
	public void onBrowserEvent(Event event) {
		Element td;
		try {
			td = getEventTargetCell(event);	
		}catch(Exception ex){
			return; 
		}
		
		if (td == null) {
            return;
          }
          Element tr = DOM.getParent(td);
          Element body = DOM.getParent(tr);
          int row = DOM.getChildIndex(body, tr);
          int column = DOM.getChildIndex(tr, td);

          switch (DOM.eventGetType(event)){
          case Event.ONMOUSEOVER: {
				if (listeners != null) {
		          listeners.fireOnRowMouseOver(event, row);
		          listeners.fireOnCellMouseOver(event, row, column);
				}
				break;
          }
          case Event.ONCLICK: {
				if (listeners != null) {
			          listeners.fireOnRowMouseClick(event, row);
			          listeners.fireOnCellMouseClick(event, row, column);
					}
					break;        	  
          }
          case Event.ONMOUSEDOWN: {
				if (listeners != null) {
		          listeners.fireOnRowMouseDown(event, row);
		          listeners.fireOnCellMouseDown(event, row, column);
				}
				break;
          }
          case Event.ONMOUSEMOVE: {
				if (listeners != null) {
		          listeners.fireOnRowMouseMove(event, row);
		          listeners.fireOnCellMouseMove(event, row, column);
				}
				break;
          }
          case Event.ONMOUSEOUT: {
				if (listeners != null) {
		          listeners.fireOnRowMouseOut(event, row);
		          listeners.fireOnCellMouseOut(event, row, column);
				}
				break;
          }
          case Event.ONMOUSEUP: {
				if (listeners != null) {
		          listeners.fireOnRowMouseUp(event, row);
		          listeners.fireOnCellMouseUp(event, row, column);
				}
				break;
          }			
    	  default: {
		  }			
		}
		super.onBrowserEvent(event);
	}
	private class TableMouseListenerCollection extends ArrayList<TableMouseListener>{

		public void fireOnCellMouseOver(Event event, int row,
				int column) {
			for(TableMouseListener listener: this)
				listener.onCellMouseOver(event, row, column);
		}

		public void fireOnRowMouseClick(Event event, int row) {
			for(TableMouseListener listener: this)
				listener.onRowMouseClick(event, row);
		}

		public void fireOnCellMouseClick(Event event, int row, int column) {
			for(TableMouseListener listener: this)
				listener.onCellMouseClick(event, row, column);
		}

		public void fireOnCellMouseUp(Event event, int row,
				int column) {
			for(TableMouseListener listener: this)
				listener.onCellMouseUp(event, row, column);
		}

		public void fireOnRowMouseUp(Event event, int row) {
			for(TableMouseListener listener: this)
				listener.onRowMouseUp(event, row);
		}

		public void fireOnCellMouseOut(Event event, int row,
				int column) {
			for(TableMouseListener listener: this)
				listener.onCellMouseOut(event, row, column);
		}

		public void fireOnRowMouseOut(Event event, int row) {
			for(TableMouseListener listener: this)
				listener.onRowMouseOut(event, row);
		}

		public void fireOnCellMouseMove(Event event, int row,
				int column) {
			for(TableMouseListener listener: this)
				listener.onCellMouseMove(event, row, column);
		}

		public void fireOnRowMouseMove(Event event, int row) {
			for(TableMouseListener listener: this)
				listener.onRowMouseMove(event, row);
		}

		public void fireOnCellMouseDown(Event event, int row,
				int column) {
			for(TableMouseListener listener: this)
				listener.onCellMouseDown(event, row, column);
		}

		public void fireOnRowMouseDown(Event event, int row) {
			for(TableMouseListener listener: this)
				listener.onRowMouseDown(event, row);
		}

		public void fireOnRowMouseOver(Event event, int row) {
			for(TableMouseListener listener: this)
				listener.onRowMouseOver(event, row);
		}
		
	}
	public interface TableMouseListener{

		void onCellMouseOver(Event event, int row, int column);

		void onRowMouseDown(Event event, int row);

		void onCellMouseDown(Event event, int row, int column);

		void onRowMouseMove(Event event, int row);

		void onCellMouseMove(Event event, int row, int column);

		void onRowMouseOut(Event event, int row);

		void onCellMouseOut(Event event, int row, int column);

		void onRowMouseUp(Event event, int row);

		void onCellMouseUp(Event event, int row, int column);

		void onRowMouseOver(Event event, int row);
		
		void onRowMouseClick(Event event, int row);

		void onCellMouseClick(Event event, int row, int column);

	}
	
	public void addTableMouseListener(TableMouseListener listener){
		if (listeners == null){ 
			 listeners = new TableMouseListenerCollection();
			 sinkEvents(Event.MOUSEEVENTS);
		}
		
		listeners.add(listener);
	}
}
